﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Tracy.DataModel;
using SharedLib;
using SharedLib.Helpers;

namespace TracyGUI.Controller.EntryTabs
{
    class SingleEntryTabPageViewController : EntryTabPageViewControllerBase, IDisposable
    {
        Entry _data;

        public Entry Data
        {
            get { return _data; }
        }

        private void Init(Entry value)
        {
            _data = value;

            //Init
            View.Name = Data.ID;
            View.Text = Data.NameWithUnwatchedCount;
            
            //Load list
            FileTabPage.LoadMediaFiles(Tracy.TracyFacade.Instance.MediaFileProvider.GetItemsByEntry(Data));
            ResTabPage.LoadResources(Tracy.TracyFacade.Instance.ResourceProvider.GetItemsByEntry(Data));

            //Tag
            TagViewController tagViewController = new TagViewController(value);
            View.AddViewToRightPanel(tagViewController.View);
            View.RightPanelCollapsed = false;
        }

        public SingleEntryTabPageViewController(Entry entry) : this()
        {
            Init(entry);
        }


        EventHandler<GenericEventArgs<IList<DataChangeSet<MediaFile>>>> _eventHandlerFileChange;
        EventHandler<GenericEventArgs<IList<MediaFile>>> _eventHandlerFileAdd;
        EventHandler<GenericEventArgs<IList<MediaFile>>> _eventHandlerFileRemove;

        public SingleEntryTabPageViewController()
            : base()
        {
            //Monitor MediaFile Provider Events
            _eventHandlerFileChange = new EventHandler<GenericEventArgs<IList<DataChangeSet<MediaFile>>>>(MediaFileProvider_ItemsChanged);
            Tracy.TracyFacade.Instance.MediaFileProvider.ItemsChanged += _eventHandlerFileChange;
            _eventHandlerFileAdd = new EventHandler<GenericEventArgs<IList<MediaFile>>>(MediaFileProvider_ItemsAdded);
            Tracy.TracyFacade.Instance.MediaFileProvider.ItemsAdded += _eventHandlerFileAdd;
            _eventHandlerFileRemove = new EventHandler<GenericEventArgs<IList<MediaFile>>>(MediaFileProvider_ItemsRemoved);
            Tracy.TracyFacade.Instance.MediaFileProvider.ItemsRemoved += _eventHandlerFileRemove;

        }
        
        private void RefreshRelatedEntries<T>(IList<T> itemList, Func<T, Entry> funcGetRelatedEntry, Func<T, bool> condition)
        {
            if (Data == null) return;
            List<string> entriesToRefresh = new List<string>();
            foreach (T item in itemList)
            {
                Entry entry = funcGetRelatedEntry(item);
                if (entry != null && entry.ID == Data.ID)
                {
                    if (condition(item))
                    {
                        _data = entry;
                        View.Text = Data.NameWithUnwatchedCount;
                    }
                }

            }
        }

        void MediaFileProvider_ItemsChanged(object sender, GenericEventArgs<IList<DataChangeSet<MediaFile>>> e)
        {
            RefreshRelatedEntries(e.Data, change => change.Data.Resource.Entry,
                change => change.OriginalData.Visible != change.Data.Visible ||
                    CommonHelper.CheckCriticalValueChange<MediaFile>(file => file.Status, "Ready", change.OriginalData, change.Data));
        }
        void MediaFileProvider_ItemsRemoved(object sender, GenericEventArgs<IList<MediaFile>> e)
        {
            RefreshRelatedEntries(e.Data, file => file.Resource.Entry, file => file.Visible == "true" && file.Status == "Ready");
        }

        void MediaFileProvider_ItemsAdded(object sender, GenericEventArgs<IList<MediaFile>> e)
        {
            RefreshRelatedEntries(e.Data, file => file.Resource.Entry, file => file.Visible == "true" && file.Status == "Ready");
        }

        #region ViewState
        public override void LoadViewState(Model.ViewStateManager manager, System.Xml.XmlElement viewStateNode)
        {
            base.LoadViewState(manager, viewStateNode);
            string entryID = viewStateNode.GetAttribute("entry-id");
            if (!string.IsNullOrEmpty(entryID))
            {
                Entry entry = Tracy.TracyFacade.Instance.EntryProvider.GetItemByID(entryID);
                if (entry != null)
                {
                    Init(entry);
                }
            }
        }

        public override void SaveViewState(Model.ViewStateManager manager, System.Xml.XmlElement viewStateNode, System.Xml.XmlDocument doc)
        {
            if (Data != null) viewStateNode.SetAttribute("entry-id", Data.ID);
            base.SaveViewState(manager, viewStateNode, doc);
        }
        #endregion

        public void Dispose()
        {
            Tracy.TracyFacade.Instance.MediaFileProvider.ItemsChanged -= _eventHandlerFileChange;
            Tracy.TracyFacade.Instance.MediaFileProvider.ItemsAdded -= _eventHandlerFileAdd;
            Tracy.TracyFacade.Instance.MediaFileProvider.ItemsRemoved -= _eventHandlerFileRemove;
        }
    }
}
